package database

import (
	"reflect"
	"strings"

	"stacks/utils"

	"gorm.io/gorm"
)

// TenantFilter 租户过滤器结构体
type TenantFilter struct {
	// 排除的表名列表
	ExcludeTables []string
	// 排除的模型类型列表
	ExcludeModels []string
}

// NewTenantFilter 创建新的租户过滤器
func NewTenantFilter() *TenantFilter {
	return &TenantFilter{
		ExcludeTables: []string{"tenants"}, // 租户表本身不需要租户过滤
		ExcludeModels: []string{"Tenant"},  // 租户模型不需要租户过滤
	}
}

// AddExcludeTable 添加排除的表名
func (tf *TenantFilter) AddExcludeTable(tableName string) {
	tf.ExcludeTables = append(tf.ExcludeTables, tableName)
}

// AddExcludeModel 添加排除的模型类型
func (tf *TenantFilter) AddExcludeModel(modelName string) {
	tf.ExcludeModels = append(tf.ExcludeModels, modelName)
}

// ShouldApplyTenantFilter 判断是否应该应用租户过滤器
func (tf *TenantFilter) ShouldApplyTenantFilter(db *gorm.DB) bool {
	// 检查表名是否在排除列表中
	if db.Statement != nil && db.Statement.Table != "" {
		for _, excludeTable := range tf.ExcludeTables {
			if strings.EqualFold(db.Statement.Table, excludeTable) {
				return false
			}
		}
	}

	// 检查模型类型是否在排除列表中
	if db.Statement != nil && db.Statement.Model != nil {
		modelType := reflect.TypeOf(db.Statement.Model)
		if modelType.Kind() == reflect.Ptr {
			modelType = modelType.Elem()
		}

		modelName := modelType.Name()
		for _, excludeModel := range tf.ExcludeModels {
			if strings.EqualFold(modelName, excludeModel) {
				return false
			}
		}
	}

	return true
}

// ApplyTenantFilter 应用租户过滤器
func (tf *TenantFilter) ApplyTenantFilter(db *gorm.DB) *gorm.DB {
	if !tf.ShouldApplyTenantFilter(db) {
		return db
	}

	// 获取当前租户ID
	tenantID := utils.GetCurrentTenantID()
	if tenantID == 0 {
		return db
	}

	// 检查是否是创建操作，如果是则自动设置租户ID
	if db.Statement != nil && db.Statement.Dest != nil {
		if err := tf.setTenantIDForCreate(db.Statement.Dest, tenantID); err != nil {
			// 如果设置失败，记录日志但不中断操作
			// 这里可以添加日志记录
		}
	}

	// 对于查询、更新、删除操作，自动添加租户ID条件
	return db.Where("tenant_id = ?", tenantID)
}

// setTenantIDForCreate 为创建操作设置租户ID
func (tf *TenantFilter) setTenantIDForCreate(dest interface{}, tenantID uint) error {
	value := reflect.ValueOf(dest)
	if value.Kind() == reflect.Ptr {
		value = value.Elem()
	}

	if value.Kind() == reflect.Struct {
		// 检查是否有TenantID字段
		tenantIDField := value.FieldByName("TenantID")
		if tenantIDField.IsValid() && tenantIDField.CanSet() {
			// 如果TenantID为0，则设置当前租户ID
			if tenantIDField.Uint() == 0 {
				tenantIDField.SetUint(uint64(tenantID))
			}
		}
	}

	return nil
}

// SkipTenantFilter 自动跳过租户过滤器（无需传递上下文）
func SkipTenantFilter() *gorm.DB {
	// 直接返回原始数据库实例，不应用任何过滤器
	return DB
}

// WithTenantFilter 创建带租户过滤器的数据库实例
func WithTenantFilter(db *gorm.DB) *gorm.DB {
	tf := NewTenantFilter()
	return db.Scopes(tf.ApplyTenantFilter)
}

// GetDBWithTenantFilter 获取带租户过滤器的数据库实例
func GetDBWithTenantFilter() *gorm.DB {
	return WithTenantFilter(DB)
}
